home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / MacTide 1.3.3 / arglib.c next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  4.0 KB  |  185 lines  |  [TEXT/MPS ]

  1. /*  Arglib.c  Manage command line switches and configuration files.
  2.     Last modified 9/18/95
  3.  
  4.     Copyright (C) 1995  David Flater.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <assert.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <ctype.h>
  26. #include "config.h"
  27. #include "arglib.h"
  28.  
  29. struct arg {
  30.   char arg[MAXARGLEN+1];
  31.   struct arg *next;
  32. };
  33.  
  34. static struct arg *args = NULL;
  35.  
  36. /* Are there more args? */
  37. int
  38. moreargs ()
  39. {
  40.   return (int)args;
  41. }
  42.  
  43. /* Is there another arg, which is not a switch?  (Doesn't start with -) */
  44. int
  45. dataarg ()
  46. {
  47.   if (args)
  48.     if (args->arg[0] != '-')
  49.       return 1;
  50.   return 0;
  51. }
  52.  
  53. /* Allocate an arg with error checking, and set its value. */
  54. static struct arg *
  55. newarg (char *s)
  56. {
  57.   struct arg *a;
  58.   assert (s);
  59.   assert ((int)(strlen (s)) <= MAXARGLEN);
  60.   assert (a = (struct arg *) malloc (sizeof (struct arg)));
  61.   strcpy (a->arg, s);
  62.   a->next = NULL;
  63.   return a;
  64. }
  65.  
  66. /* Push an arg onto the arg stack. */
  67. static void
  68. pusharg (struct arg *a)
  69. {
  70.   a->next = args;
  71.   args = a;
  72. }
  73.  
  74. /* Pop an arg, returning a pointer to static memory or NULL if no more
  75.    args. */
  76. char *
  77. poparg ()
  78. {
  79.   static char savearg[MAXARGLEN+1];
  80.   struct arg *delme;
  81.   if (!args)
  82.     return NULL;
  83.   strcpy (savearg, args->arg);
  84.   delme = args;
  85.   args = args->next;
  86.   free (delme);
  87.   return savearg;
  88. }
  89.  
  90. /* Stack the command line */
  91. void
  92. push_command_line (int argc, char **argv)
  93. {
  94.   assert (argc > 0);
  95.   for (argc--;argc;argc--)
  96.     pusharg (newarg (argv[argc]));
  97. }
  98.  
  99. /* Kill a comment in a config file. */
  100. void
  101. killcomment (FILE *fp)
  102. {
  103.   int t;
  104.   do {
  105.     t = fgetc (fp);
  106.     if (t == '\n' || t == '\r')
  107.       break;
  108.   } while (t != EOF);
  109. }
  110.  
  111. /* Scan an arg from a file, returning a pointer to static memory or NULL
  112.    if end of file. */
  113. static char *
  114. farg (FILE *fp)
  115. {
  116.   static char savearg[MAXARGLEN+1];
  117.   int len = 0, t, isdelim = 0;
  118.   while (1) {
  119.     /* Skip leading whitespace */
  120.     do {
  121.       if ((t = fgetc (fp)) == EOF)
  122.         return NULL;
  123.     } while (isspace (t));
  124.     /* Kill those comments */
  125.     if (t == '#')
  126.       killcomment (fp);
  127.     else
  128.       break;
  129.   }
  130.   /* Is this a delimited arg? */
  131.   if (t == '"')
  132.     isdelim = 1;
  133.   else
  134.     savearg[len++] = (char)t;
  135.   /* Read it in */
  136.   while ((t = fgetc (fp)) != EOF) {
  137.     if ((t == '"' && isdelim) || (isspace (t) && !isdelim) || t == '#')
  138.       break;
  139.     savearg[len++] = (char)t;
  140.     assert (len <= MAXARGLEN);
  141.   }
  142.   assert (len <= MAXARGLEN);
  143.   savearg[len] = '\0';
  144.   return savearg;
  145. }
  146.  
  147. /* Stack the contents of a file.  The -config option is specifically
  148.    rejected to avoid recursive definitions and attacks launched through
  149.    CGI scripts.
  150.  
  151.    Returns 0 if the reading of the file is unsuccessful.
  152. */
  153. int
  154. push_config_file (char *fname)
  155. {
  156.   FILE *fp;
  157.   struct arg *revstack = NULL, *temparg;
  158.   char *filearg;
  159.   assert (fname);
  160.   if (!strcmp (fname, "-"))
  161.     fp = stdin;
  162.   else {
  163.     if (!(fp = fopen (fname, "r")))
  164.       return 0;
  165.   }
  166.   /* Store the args temporarily in reverse order */
  167.   while ((filearg = farg (fp))) {
  168.     if (!strcmp (filearg, "-config")) {
  169.       fprintf (stderr, "arglib:  -config only allowed on command line\n");
  170.       exit (-1);
  171.     }
  172.     temparg = newarg (filearg);
  173.     temparg->next = revstack;
  174.     revstack = temparg;
  175.   }
  176.   fclose (fp);
  177.   /* Push them on the stack in the correct order */
  178.   while (revstack) {
  179.     temparg = revstack;
  180.     revstack = revstack->next;
  181.     pusharg (temparg);
  182.   }
  183.   return 1;
  184. }
  185.